package com.ruoyi.business.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.domain.EquipmentTypes;
import com.ruoyi.business.domain.EquipmentVariables;
import com.ruoyi.business.mapper.EquipmentTypesMapper;
import com.ruoyi.business.mapper.EquipmentVariablesMapper;
import com.ruoyi.business.service.IEquipmentTypesService;
import com.ruoyi.business.vo.DeviceVariableStatisticsVO;
import com.ruoyi.business.vo.EquipmentStatisticsVO;
import com.ruoyi.business.vo.EquipmentTypeTreeVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 存储设备类型信息的，支持树状结构Service业务层处理
 * 
 * @author ldkj
 * @date 2025-02-27
 */
@Service
public class EquipmentTypesServiceImpl extends ServiceImpl<EquipmentTypesMapper, EquipmentTypes>  implements IEquipmentTypesService
{
    @Autowired
    private EquipmentTypesMapper equipmentTypesMapper;

    @Autowired
    private EquipmentVariablesMapper equipmentVariablesMapper;

    /**
     * 查询存储设备类型信息的，支持树状结构
     * 
     * @param equipmentTypeId 存储设备类型信息的，支持树状结构主键
     * @return 存储设备类型信息的，支持树状结构
     */
    @Override
    public EquipmentTypes selectEquipmentTypesByEquipmentTypeId(Long equipmentTypeId)
    {
        return equipmentTypesMapper.selectEquipmentTypesByEquipmentTypeId(equipmentTypeId);
    }

    /**
     * 查询存储设备类型信息的，支持树状结构列表
     * 
     * @param equipmentTypes 存储设备类型信息的，支持树状结构
     * @return 存储设备类型信息的，支持树状结构
     */
    @Override
    public List<EquipmentTypes> selectEquipmentTypesList(EquipmentTypes equipmentTypes)
    {
        return equipmentTypesMapper.selectEquipmentTypesList(equipmentTypes);
    }

    /**
     * 新增存储设备类型信息的，支持树状结构
     * 
     * @param equipmentTypes 存储设备类型信息的，支持树状结构
     * @return 结果
     */
    @Override
    public int insertEquipmentTypes(EquipmentTypes equipmentTypes)
    {
        // 如果equipmentTypeId为空，生成一个ID
        if (equipmentTypes.getEquipmentTypeId() == null) {
            equipmentTypes.setEquipmentTypeId(getNextEquipmentTypeId());
        }
        return equipmentTypesMapper.insertEquipmentTypes(equipmentTypes);
    }

    /**
     * 修改存储设备类型信息的，支持树状结构
     *
     * @param equipmentTypes 存储设备类型信息的，支持树状结构
     * @return 结果
     */
    @Override
    public int updateEquipmentTypes(EquipmentTypes equipmentTypes)
    {
        return equipmentTypesMapper.updateEquipmentTypes(equipmentTypes);
    }

    /**
     * 批量删除存储设备类型信息的，支持树状结构
     *
     * @param equipmentTypeIds 需要删除的存储设备类型信息的，支持树状结构主键
     * @return 结果
     */
    @Override
    public int deleteEquipmentTypesByEquipmentTypeIds(Long[] equipmentTypeIds)
    {
        return equipmentTypesMapper.deleteEquipmentTypesByEquipmentTypeIds(equipmentTypeIds);
    }

    /**
     * 删除存储设备类型信息的，支持树状结构信息
     *
     * @param equipmentTypeId 存储设备类型信息的，支持树状结构主键
     * @return 结果
     */
    @Override
    public int deleteEquipmentTypesByEquipmentTypeId(Long equipmentTypeId)
    {
        return equipmentTypesMapper.deleteEquipmentTypesByEquipmentTypeId(equipmentTypeId);
    }




    /**
     * 导入设备类型数据
     *
     * @param equipmentTypesList 设备类型数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，是否进行更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    public String importEquipmentTypes(List<EquipmentTypes> equipmentTypesList, Boolean isUpdateSupport, String operName)
    {
        if (equipmentTypesList == null || equipmentTypesList.size() == 0)
        {
            throw new RuntimeException("导入设备类型数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (EquipmentTypes equipmentTypes : equipmentTypesList)
        {
            try
            {
                // 验证必填字段
                if (equipmentTypes.getEquipmentTypeName() == null || equipmentTypes.getEquipmentTypeName().trim().isEmpty())
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、设备类型名称不能为空");
                    continue;
                }

                // 处理父级设备类型名称到ID的转换
                if (equipmentTypes.getParentEquipmentTypeName() != null && !equipmentTypes.getParentEquipmentTypeName().trim().isEmpty())
                {
                    // 根据父级设备类型名称查找对应的ID
                    EquipmentTypes parentQuery = new EquipmentTypes();
                    parentQuery.setEquipmentTypeName(equipmentTypes.getParentEquipmentTypeName().trim());
                    List<EquipmentTypes> parentList = equipmentTypesMapper.selectEquipmentTypesList(parentQuery);

                    if (parentList.size() > 0)
                    {
                        equipmentTypes.setParentEquipmentTypeId(parentList.get(0).getEquipmentTypeId());
                    }
                    else
                    {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + "、设备类型 " + equipmentTypes.getEquipmentTypeName() + " 的父级设备类型 '" + equipmentTypes.getParentEquipmentTypeName() + "' 不存在");
                        continue;
                    }
                }
                else
                {
                    // 父级设备类型名称为空，设置为根节点
                    equipmentTypes.setParentEquipmentTypeId(null);
                }

                // 处理其他可能为空的数值字段
                if (equipmentTypes.getWarrantyPeriod() != null && equipmentTypes.getWarrantyPeriod() == 0)
                {
                    equipmentTypes.setWarrantyPeriod(null);
                }
                if (equipmentTypes.getUsageCount() != null && equipmentTypes.getUsageCount() == 0)
                {
                    equipmentTypes.setUsageCount(null);
                }
                if (equipmentTypes.getExpUsageCount() != null && equipmentTypes.getExpUsageCount() == 0)
                {
                    equipmentTypes.setExpUsageCount(null);
                }
                if (equipmentTypes.getRemUsageCount() != null && equipmentTypes.getRemUsageCount() == 0)
                {
                    equipmentTypes.setRemUsageCount(null);
                }

                // 验证是否存在这个设备类型名称
                EquipmentTypes existEquipmentTypes = new EquipmentTypes();
                existEquipmentTypes.setEquipmentTypeName(equipmentTypes.getEquipmentTypeName());
                List<EquipmentTypes> existList = equipmentTypesMapper.selectEquipmentTypesList(existEquipmentTypes);

                if (existList.size() == 0)
                {
                    // 不存在，新增
                    // 生成下一个ID（临时方案，直到数据库表结构修改为自增）
                    equipmentTypes.setEquipmentTypeId(getNextEquipmentTypeId());
                    // 使用 MyBatis-Plus 的 save 方法
                    this.save(equipmentTypes);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、设备类型 " + equipmentTypes.getEquipmentTypeName() + " 导入成功");
                }
                else if (isUpdateSupport)
                {
                    // 存在且支持更新，更新数据
                    EquipmentTypes existEquipment = existList.get(0);
                    equipmentTypes.setEquipmentTypeId(existEquipment.getEquipmentTypeId());
                    // 使用 MyBatis-Plus 的 updateById 方法
                    this.updateById(equipmentTypes);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、设备类型 " + equipmentTypes.getEquipmentTypeName() + " 更新成功");
                }
                else
                {
                    // 存在且不支持更新，跳过（不计入失败）
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、设备类型 " + equipmentTypes.getEquipmentTypeName() + " 已存在，跳过");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String equipmentName = equipmentTypes != null && equipmentTypes.getEquipmentTypeName() != null ? 
                    equipmentTypes.getEquipmentTypeName() : "未知设备";
                String msg = "<br/>" + failureNum + "、设备类型 " + equipmentName + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0)
        {
            if (successNum > 0)
            {
                return "导入完成！成功 " + successNum + " 条，失败 " + failureNum + " 条。" + 
                       "成功信息：" + successMsg.toString() + "失败信息：" + failureMsg.toString();
            }
            else
            {
                failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
                throw new RuntimeException(failureMsg.toString());
            }
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入完成！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 查询存储设备类型信息的，支持树状结构列表（用于导出，包含父级设备类型名称）
     * 
     * @param equipmentTypes 存储设备类型信息的，支持树状结构
     * @return 存储设备类型信息的，支持树状结构集合
     */
    @Override
    public List<EquipmentTypes> selectEquipmentTypesListForExport(EquipmentTypes equipmentTypes)
    {
        List<EquipmentTypes> list = equipmentTypesMapper.selectEquipmentTypesList(equipmentTypes);
        
        // 填充父级设备类型名称
        for (EquipmentTypes item : list)
        {
            if (item.getParentEquipmentTypeId() != null)
            {
                EquipmentTypes parent = equipmentTypesMapper.selectEquipmentTypesByEquipmentTypeId(item.getParentEquipmentTypeId());
                if (parent != null)
                {
                    item.setParentEquipmentTypeName(parent.getEquipmentTypeName());
                }
            }
        }
        
        return list;
    }

    /**
     * 获取下一个设备类型ID（临时方案，直到数据库表结构修改为自增）
     * 
     * @return 下一个ID
     */
    private Long getNextEquipmentTypeId()
    {
        // 查询当前最大ID
        List<EquipmentTypes> allList = equipmentTypesMapper.selectEquipmentTypesList(new EquipmentTypes());
        Long maxId = 0L;
        
        for (EquipmentTypes item : allList)
        {
            if (item.getEquipmentTypeId() != null && item.getEquipmentTypeId() > maxId)
            {
                maxId = item.getEquipmentTypeId();
            }
        }
        
//        // 如果最大ID小于10000，从10000开始
//        if (maxId < 10000L)
//        {
//            return 10000L;
//        }
        
        // 否则返回最大ID + 1
        return maxId + 1;
    }

    /**
     * 根据设备类型名称查询设备类型树状结构（包含所有子类和关联的设备变量）
     * 
     * @param equipmentTypeName 设备类型名称
     * @return 设备类型树状结构
     */
    @Override
    public EquipmentTypeTreeVO selectEquipmentTypeTreeByName(String equipmentTypeName) {
        // 1. 递归查询所有子类设备类型
        List<EquipmentTypes> allEquipmentTypes = equipmentTypesMapper.selectChildrenByEquipmentTypeName(equipmentTypeName);
        
        if (allEquipmentTypes == null || allEquipmentTypes.isEmpty()) {
            return null;
        }
        
        // 2. 获取所有设备类型ID列表
        List<Long> equipmentTypeIds = allEquipmentTypes.stream()
                .map(EquipmentTypes::getEquipmentTypeId)
                .collect(Collectors.toList());
        
        // 3. 批量查询所有相关的设备变量（通过设备类型ID关联）
        List<EquipmentVariables> allVariables = equipmentVariablesMapper.selectEquipmentVariablesByTypeIds(equipmentTypeIds);
        
        // 4. 按设备类型ID对变量进行分组
        Map<Long, List<EquipmentVariables>> variableMap = new HashMap<>();
        for (EquipmentVariables variable : allVariables) {
            Long typeId = variable.getSecondaryEquipmentTypeId();
            variableMap.computeIfAbsent(typeId, k -> new ArrayList<>()).add(variable);
        }
        
        // 5. 构建树状结构
        return buildEquipmentTypeTreeById(allEquipmentTypes, variableMap, equipmentTypeName);
    }


    /**
     * 根据设备类型名称查询设备变量平均值
     *
     * @param equipmentTypeName 设备类型名称
     * @return DeviceVariableStatisticsVO
     */
    @Override
    public DeviceVariableStatisticsVO selectEquipmentTypeAvgByName(String equipmentTypeName) {
        List<String> targetVariableNames = Arrays.asList(
                "mildMildfurntemp",   // MILD炉_温度探头1实际温度
                "mildMildfurntemp1",
                "mildMildfurntemp2",
                "mildMildfurntemp3"
        ); // 目标变量的英文名称列表

        // 1. 递归查询所有子类设备类型
        List<EquipmentTypes> allEquipmentTypes = equipmentTypesMapper.selectChildrenByEquipmentTypeName(equipmentTypeName);

        if (allEquipmentTypes == null || allEquipmentTypes.isEmpty()) {
            return null;
        }

        // 2. 获取所有设备类型ID列表
        List<Long> equipmentTypeIds = allEquipmentTypes.stream()
                .map(EquipmentTypes::getEquipmentTypeId)
                .collect(Collectors.toList());

        // 3. 批量查询所有相关的设备变量（通过设备类型ID关联）
        List<EquipmentVariables> allVariables = equipmentVariablesMapper.selectEquipmentVariablesByTypeIds(equipmentTypeIds);

        // 4. 根据目标变量名过滤设备变量
        List<EquipmentVariables> targetVariables = allVariables.stream()
                .filter(variable -> targetVariableNames.contains(variable.getVariableEnName())) // 使用英文名称
                .collect(Collectors.toList());

        // 5. 计算目标变量的平均值
        if (targetVariables.isEmpty()) {
            return null; // 如果没有找到相关变量
        }

        // 提取变量值并计算平均值
        List<Double> values = targetVariables.stream()
                .map(variable -> {
                    try {
                        return Double.parseDouble(variable.getVariableValue());
                    } catch (NumberFormatException e) {
                        return null; // 如果无法转换为数字，忽略此值
                    }
                })
                .filter(Objects::nonNull) // 过滤掉无效的值
                .collect(Collectors.toList());

        // 如果没有有效的数值，则返回 null
        if (values.isEmpty()) {
            return null;
        }

        // 计算平均值并直接截断到两位小数
        double averageValue = values.stream()
                .mapToDouble(Double::doubleValue)
                .average()
                .orElse(0.0);

        // 使用BigDecimal直接截断到两位小数
        BigDecimal averageValueDecimal = new BigDecimal(averageValue).setScale(2, RoundingMode.DOWN);


        // 返回计算结果
        return new DeviceVariableStatisticsVO(equipmentTypeName, averageValueDecimal.doubleValue());
    }



    /**
     * 查询设备数统计信息列表
     * @return
     */
    @Override
    public List<EquipmentStatisticsVO> getEquipmentStatistics() {
        return equipmentTypesMapper.selectSecondLevelThirdStatistics();
    }
    
    /**
     * 构建设备类型树状结构
     * 
     * @param allEquipmentTypes 所有设备类型列表
     * @param variableMap 变量映射表
     * @param rootTypeName 根节点类型名称
     * @return 树状结构根节点
     */
    private EquipmentTypeTreeVO buildEquipmentTypeTree(List<EquipmentTypes> allEquipmentTypes, 
                                                       Map<String, List<EquipmentVariables>> variableMap, 
                                                       String rootTypeName) {
        // 将设备类型转换为VO并按ID分组
        Map<Long, EquipmentTypeTreeVO> typeMap = new HashMap<>();
        Map<String, EquipmentTypeTreeVO> nameMap = new HashMap<>();
        
        for (EquipmentTypes equipmentType : allEquipmentTypes) {
            EquipmentTypeTreeVO treeVO = convertToTreeVO(equipmentType);
            
            // 设置关联的变量列表
            List<EquipmentVariables> variables = variableMap.get(equipmentType.getEquipmentTypeName());
            if (variables != null) {
                treeVO.setVariables(variables);
            }
            
            typeMap.put(equipmentType.getEquipmentTypeId(), treeVO);
            nameMap.put(equipmentType.getEquipmentTypeName(), treeVO);
        }
        
        // 构建父子关系
        EquipmentTypeTreeVO root = null;
        for (EquipmentTypes equipmentType : allEquipmentTypes) {
            EquipmentTypeTreeVO current = typeMap.get(equipmentType.getEquipmentTypeId());
            
            if (equipmentType.getParentEquipmentTypeId() != null) {
                // 有父节点，添加到父节点的children中
                EquipmentTypeTreeVO parent = typeMap.get(equipmentType.getParentEquipmentTypeId());
                if (parent != null) {
                    parent.addChild(current);
                }
            } else if (equipmentType.getEquipmentTypeName().equals(rootTypeName)) {
                // 没有父节点且是指定的根节点
                root = current;
            }
        }
        
        // 如果没有找到根节点，尝试从名称映射中获取
        if (root == null) {
            root = nameMap.get(rootTypeName);
        }
        
        return root;
    }
    
    /**
     * 构建设备类型树状结构（通过设备类型ID关联变量）
     * 
     * @param allEquipmentTypes 所有设备类型列表
     * @param variableMap 变量映射表（按设备类型ID分组）
     * @param rootTypeName 根节点类型名称
     * @return 树状结构根节点
     */
    private EquipmentTypeTreeVO buildEquipmentTypeTreeById(List<EquipmentTypes> allEquipmentTypes, 
                                                          Map<Long, List<EquipmentVariables>> variableMap, 
                                                          String rootTypeName) {
        // 将设备类型转换为VO并按ID分组
        Map<Long, EquipmentTypeTreeVO> typeMap = new HashMap<>();
        Map<String, EquipmentTypeTreeVO> nameMap = new HashMap<>();
        
        for (EquipmentTypes equipmentType : allEquipmentTypes) {
            EquipmentTypeTreeVO treeVO = convertToTreeVO(equipmentType);
            
            // 设置关联的变量列表（通过设备类型ID关联）
            List<EquipmentVariables> variables = variableMap.get(equipmentType.getEquipmentTypeId());
            if (variables != null) {
                treeVO.setVariables(variables);
            }
            
            typeMap.put(equipmentType.getEquipmentTypeId(), treeVO);
            nameMap.put(equipmentType.getEquipmentTypeName(), treeVO);
        }
        
        // 构建父子关系
        EquipmentTypeTreeVO root = null;
        for (EquipmentTypes equipmentType : allEquipmentTypes) {
            EquipmentTypeTreeVO current = typeMap.get(equipmentType.getEquipmentTypeId());
            
            if (equipmentType.getParentEquipmentTypeId() != null) {
                // 有父节点，添加到父节点的children中
                EquipmentTypeTreeVO parent = typeMap.get(equipmentType.getParentEquipmentTypeId());
                if (parent != null) {
                    parent.addChild(current);
                }
            } else if (equipmentType.getEquipmentTypeName().equals(rootTypeName)) {
                // 没有父节点且是指定的根节点
                root = current;
            }
        }
        
        // 如果没有找到根节点，尝试从名称映射中获取
        if (root == null) {
            root = nameMap.get(rootTypeName);
        }
        
        return root;
    }
    
    /**
     * 将EquipmentTypes转换为EquipmentTypeTreeVO
     * 
     * @param equipmentType 设备类型实体
     * @return 树状结构VO
     */
    private EquipmentTypeTreeVO convertToTreeVO(EquipmentTypes equipmentType) {
        EquipmentTypeTreeVO treeVO = new EquipmentTypeTreeVO();
        BeanUtils.copyProperties(equipmentType, treeVO);
        return treeVO;
    }


}
